package com.pick.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pick.admin.service.SysUserRoleService;
import com.pick.admin.entity.SysUserRole;
import com.pick.admin.entity.SysUserPermission;
import com.pick.admin.entity.SysMenu;
import com.pick.admin.entity.SysUserMenu;
import com.pick.admin.entity.SysRoleMenu;
import com.pick.admin.mapper.SysUserRoleMapper;
import com.pick.admin.mapper.SysUserPermissionMapper;
import com.pick.admin.mapper.SysRolePermissionMapper;
import com.pick.admin.mapper.SysMenuMapper;
import com.pick.admin.mapper.SysUserMenuMapper;
import com.pick.admin.mapper.SysRoleMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户角色服务实现类
 *
 * @author pick
 * @since 2024-01-01
 */
@Service
public class SysUserRoleServiceImpl implements SysUserRoleService {

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysUserPermissionMapper sysUserPermissionMapper;

    @Autowired
    private SysRolePermissionMapper sysRolePermissionMapper;
    
    @Autowired
    private SysMenuMapper sysMenuMapper;
    
    @Autowired
    private SysUserMenuMapper sysUserMenuMapper;
    
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    @Transactional
    public void assignRoles(Long userId, List<Long> roleIds) {
        // 先删除用户现有的角色关联
        LambdaQueryWrapper<SysUserRole> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysUserRole::getUserId, userId);
        sysUserRoleMapper.delete(deleteWrapper);

        // 添加新的角色关联
        if (roleIds != null && !roleIds.isEmpty()) {
            List<SysUserRole> userRoles = roleIds.stream()
                    .map(roleId -> {
                        SysUserRole userRole = new SysUserRole();
                        userRole.setUserId(userId);
                        userRole.setRoleId(roleId);
                        userRole.setCreateTime(LocalDateTime.now());
                        userRole.setUpdateTime(LocalDateTime.now());
                        return userRole;
                    })
                    .toList();

            userRoles.forEach(sysUserRoleMapper::insert);
        }
    }

    @Override
    @Transactional
    public void removeUserRole(Long userId, Long roleId) {
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId, userId)
                .eq(SysUserRole::getRoleId, roleId);
        sysUserRoleMapper.delete(wrapper);
    }

    @Override
    @Transactional
    public void removeUserRoles(Long userId, List<Long> roleIds) {
        if (roleIds != null && !roleIds.isEmpty()) {
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId, userId)
                    .in(SysUserRole::getRoleId, roleIds);
            sysUserRoleMapper.delete(wrapper);
        }
    }

    @Override
    public List<Long> getUserRoleIds(Long userId) {
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoles = sysUserRoleMapper.selectList(wrapper);
        return userRoles.stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toList());
    }

    @Override
    public List<Long> getUserPermissionIds(Long userId) {
        return sysUserPermissionMapper.selectPermissionIdsByUserId(userId);
    }

    @Override
    @Transactional
    public void assignUserPermissions(Long userId, List<Long> permissionIds) {
        // 先删除用户现有的直接权限
        LambdaQueryWrapper<SysUserPermission> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.eq(SysUserPermission::getUserId, userId);
        sysUserPermissionMapper.delete(deleteWrapper);

        // 添加新的权限
        if (permissionIds != null && !permissionIds.isEmpty()) {
            List<SysUserPermission> userPermissions = permissionIds.stream()
                    .map(permissionId -> {
                        SysUserPermission userPermission = new SysUserPermission();
                        userPermission.setUserId(userId);
                        userPermission.setPermissionId(permissionId);
                        userPermission.setCreateTime(LocalDateTime.now());
                        userPermission.setUpdateTime(LocalDateTime.now());
                        return userPermission;
                    })
                    .toList();

            userPermissions.forEach(sysUserPermissionMapper::insert);
        }
    }

    @Override
    public boolean hasRole(Long userId, String roleCode) {
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoles = sysUserRoleMapper.selectList(wrapper);
        
        // 这里需要根据角色ID查询角色代码，简化处理
        // 实际项目中可能需要关联查询sys_role表
        return !userRoles.isEmpty();
    }

    @Override
    public boolean hasPermission(Long userId, String permissionCode) {
        // 检查用户直接分配的权限
        List<Long> userPermissionIds = getUserPermissionIds(userId);
        
        // 这里需要根据权限ID查询权限代码，简化处理
        // 实际项目中可能需要关联查询sys_permission表
        return !userPermissionIds.isEmpty();
    }
    
    @Override
    public List<String> getUserPermissionCodes(Long userId) {
        // 获取用户权限代码列表的实现
        // 这里简化处理，实际项目中需要关联查询
        return List.of();
    }
    
    @Override
    @Transactional
    public boolean assignUserMenus(Long userId, List<Long> menuIds) {
        try {
            // 先删除用户现有的菜单权限
            LambdaQueryWrapper<SysUserMenu> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(SysUserMenu::getUserId, userId);
            sysUserMenuMapper.delete(deleteWrapper);

            // 添加新的菜单权限
            if (menuIds != null && !menuIds.isEmpty()) {
                List<SysUserMenu> userMenus = menuIds.stream()
                        .map(menuId -> {
                            SysUserMenu userMenu = new SysUserMenu();
                            userMenu.setUserId(userId);
                            userMenu.setMenuId(menuId);
                            userMenu.setCreateTime(LocalDateTime.now());
                            userMenu.setUpdateTime(LocalDateTime.now());
                            return userMenu;
                        })
                        .toList();

                userMenus.forEach(sysUserMenuMapper::insert);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public List<SysMenu> getUserMenus(Long userId) {
        // 获取用户直接分配的菜单
        LambdaQueryWrapper<SysUserMenu> userMenuWrapper = new LambdaQueryWrapper<>();
        userMenuWrapper.eq(SysUserMenu::getUserId, userId);
        List<SysUserMenu> userMenus = sysUserMenuMapper.selectList(userMenuWrapper);

        // 添加用户直接分配的菜单ID
        Set<Long> menuIds = userMenus.stream()
                .map(SysUserMenu::getMenuId).collect(Collectors.toSet());
        
        // 获取用户角色的菜单
        List<Long> userRoleIds = getUserRoleIds(userId);
        for (Long roleId : userRoleIds) {
            LambdaQueryWrapper<SysRoleMenu> roleMenuWrapper = new LambdaQueryWrapper<>();
            roleMenuWrapper.eq(SysRoleMenu::getRoleId, roleId);
            List<SysRoleMenu> roleMenus = sysRoleMenuMapper.selectList(roleMenuWrapper);
            menuIds.addAll(roleMenus.stream()
                    .map(SysRoleMenu::getMenuId)
                    .collect(Collectors.toSet()));
        }
        
        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 查询菜单详情
        LambdaQueryWrapper<SysMenu> menuWrapper = new LambdaQueryWrapper<>();
        menuWrapper.in(SysMenu::getId, menuIds)
                   .eq(SysMenu::getStatus, 1)
                   .orderByAsc(SysMenu::getSortOrder);
        return sysMenuMapper.selectList(menuWrapper);
    }
    
    @Override
    @Transactional
    public boolean assignRoleMenus(Long roleId, List<Long> menuIds) {
        try {
            // 先删除角色现有的菜单权限
            LambdaQueryWrapper<SysRoleMenu> deleteWrapper = new LambdaQueryWrapper<>();
            deleteWrapper.eq(SysRoleMenu::getRoleId, roleId);
            sysRoleMenuMapper.delete(deleteWrapper);

            // 添加新的菜单权限
            if (menuIds != null && !menuIds.isEmpty()) {
                List<SysRoleMenu> roleMenus = menuIds.stream()
                        .map(menuId -> {
                            SysRoleMenu roleMenu = new SysRoleMenu();
                            roleMenu.setRoleId(roleId);
                            roleMenu.setMenuId(menuId);
                            roleMenu.setCreateTime(LocalDateTime.now());
                            roleMenu.setUpdateTime(LocalDateTime.now());
                            return roleMenu;
                        })
                        .toList();

                roleMenus.forEach(sysRoleMenuMapper::insert);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    @Override
    public List<SysMenu> getRoleMenus(Long roleId) {
        // 获取角色的菜单权限
        LambdaQueryWrapper<SysRoleMenu> roleMenuWrapper = new LambdaQueryWrapper<>();
        roleMenuWrapper.eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> roleMenus = sysRoleMenuMapper.selectList(roleMenuWrapper);
        
        if (roleMenus.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Long> menuIds = roleMenus.stream()
                .map(SysRoleMenu::getMenuId)
                .collect(Collectors.toList());
        
        // 查询菜单详情
        LambdaQueryWrapper<SysMenu> menuWrapper = new LambdaQueryWrapper<>();
        menuWrapper.in(SysMenu::getId, menuIds)
                   .eq(SysMenu::getStatus, 1)
                   .orderByAsc(SysMenu::getSortOrder);
        return sysMenuMapper.selectList(menuWrapper);
    }
}